/*
This file is part of Arcadeflex.

Arcadeflex is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Arcadeflex is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Arcadeflex.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * ported to v0.28
 * ported to v0.27
 *
 *
 *
 */

package vidhrdw;

import static arcadeflex.libc.*;
import static mame.common.*;
import static mame.commonH.*;
import static mame.driverH.*;
import static mame.mame.*;
import static mame.osdependH.*;
import static arcadeflex.osdepend.*;
import static vidhrdw.generic.*;

public class _1942
{


	public static int[] c1942_backgroundram_size = new int[1];
	public static CharPtr c1942_backgroundram = new CharPtr();
	public static CharPtr c1942_scroll = new CharPtr();
	public static CharPtr c1942_palette_bank = new CharPtr();
	static char []dirtybuffer2;
	static osd_bitmap tmpbitmap2;
        static int flipscreen;


        static int TOTAL_COLORS(int gfxn) 
        {
            return Machine.gfx[gfxn].total_colors * Machine.gfx[gfxn].color_granularity;
        }
        
	public static VhConvertColorPromPtr c1942_vh_convert_color_prom = new VhConvertColorPromPtr() { public void handler(char []palette_table, char []colortable_table, char []color_prom_table)
	{
                int i;
                CharPtr color_prom = new CharPtr(color_prom_table);
                CharPtr palette= new CharPtr(palette_table);
                for (i = 0;i < Machine.drv.total_colors;i++)
		{
			int bit0,bit1,bit2,bit3;
	
	
			bit0 = (color_prom.read(0) >> 0) & 0x01;
			bit1 = (color_prom.read(0) >> 1) & 0x01;
			bit2 = (color_prom.read(0) >> 2) & 0x01;
			bit3 = (color_prom.read(0) >> 3) & 0x01;
			palette.writeinc(0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
			bit0 = (color_prom.read(Machine.drv.total_colors) >> 0) & 0x01;
			bit1 = (color_prom.read(Machine.drv.total_colors) >> 1) & 0x01;
			bit2 = (color_prom.read(Machine.drv.total_colors) >> 2) & 0x01;
			bit3 = (color_prom.read(Machine.drv.total_colors) >> 3) & 0x01;
			palette.writeinc(0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
			bit0 = (color_prom.read(2*Machine.drv.total_colors) >> 0) & 0x01;
			bit1 = (color_prom.read(2*Machine.drv.total_colors) >> 1) & 0x01;
			bit2 = (color_prom.read(2*Machine.drv.total_colors) >> 2) & 0x01;
			bit3 = (color_prom.read(2*Machine.drv.total_colors) >> 3) & 0x01;
			palette.writeinc(0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
	
			color_prom.inc();
		}
                color_prom.inc(2*Machine.drv.total_colors);
		/* color_prom now points to the beginning of the lookup table */
	
	
		/* characters use colors 128-143 */
		for (i = 0;i < TOTAL_COLORS(0);i++)
			colortable_table[Machine.drv.gfxdecodeinfo[0].color_codes_start + i] = (char) ((color_prom.readinc()) + 128);
	
		/* background tiles use colors 0-63 in four banks */
		for (i = 0;i < TOTAL_COLORS(1)/4;i++)
		{
			colortable_table[Machine.drv.gfxdecodeinfo[1].color_codes_start + i] = color_prom.read();
                        colortable_table[Machine.drv.gfxdecodeinfo[1].color_codes_start + i+32*8] = (char) ((color_prom.read()) + 16);
			colortable_table[Machine.drv.gfxdecodeinfo[1].color_codes_start + i+2*32*8] = (char) ((color_prom.read()) + 32);
			colortable_table[Machine.drv.gfxdecodeinfo[1].color_codes_start + i+3*32*8] = (char) ((color_prom.read()) + 48);
			color_prom.inc();
		}
	
		/* sprites use colors 64-79 */
		for (i = 0;i < TOTAL_COLORS(2);i++)
                    colortable_table[Machine.drv.gfxdecodeinfo[2].color_codes_start + i] = (char) ((color_prom.readinc()) + 64);

		
	} };



	/***************************************************************************

	  Start the video hardware emulation.

	***************************************************************************/
	public static VhStartPtr c1942_vh_start = new VhStartPtr() { public int handler()
	{
		if (generic_vh_start.handler() != 0)
			return 1;
	        if ((dirtybuffer2 = new char[c1942_backgroundram_size[0]]) == null)
		{
			generic_vh_stop.handler();
			return 1;
		}
		memset(dirtybuffer2, 1, c1942_backgroundram_size[0]);

		/* the background area is twice as wide as the screen (actually twice as tall, */
		/* because this is a vertical game) */
		if ((tmpbitmap2 = osd_create_bitmap(2*Machine.drv.screen_width,Machine.drv.screen_height)) == null)
		{
			dirtybuffer2 = null;
			generic_vh_stop.handler();
			return 1;
		}

		return 0;
	} };



	/***************************************************************************

	  Stop the video hardware emulation.

	***************************************************************************/
	public static VhStopPtr c1942_vh_stop = new VhStopPtr() { public void handler()
	{
		osd_free_bitmap(tmpbitmap2);
		tmpbitmap2 = null;
		dirtybuffer2 = null;
		generic_vh_stop.handler();
	} };



	public static WriteHandlerPtr c1942_background_w = new WriteHandlerPtr() { public void handler(int offset,int data)
	{
		if (c1942_backgroundram.read(offset) != data)
		{
			dirtybuffer2[offset] = 1;

			c1942_backgroundram.write(offset, data);
		}
	} };



	public static WriteHandlerPtr c1942_palette_bank_w = new WriteHandlerPtr() { public void handler(int offset,int data)
	{
		if (c1942_palette_bank.read() != data)
		{
			int i;


			memset(dirtybuffer2, 1, c1942_backgroundram_size[0]);

			c1942_palette_bank.write(data);
		}
	} };

        public static WriteHandlerPtr c1942_flipscreen_w = new WriteHandlerPtr() { public void handler(int offset, int data)
	{
		if (flipscreen != (data & 0x80))
		{
			flipscreen = data & 0x80;
			memset(dirtybuffer2,1,c1942_backgroundram_size[0]);
		}
	} };

	/***************************************************************************

	  Draw the game screen in the given osd_bitmap.
	  Do NOT call osd_update_display() from this function, it will be called by
	  the main emulation engine.

	***************************************************************************/
	public static VhUpdatePtr c1942_vh_screenrefresh = new VhUpdatePtr() { public void handler(osd_bitmap bitmap)
	{
		int offs;
	
	
		for (offs = c1942_backgroundram_size[0] - 1;offs >= 0;offs--)
		{
			if ((offs & 0x10) == 0 && (dirtybuffer2[offs] != 0 || dirtybuffer2[offs + 16] != 0))
			{
				int sx,sy,flipx,flipy;
	
	
				dirtybuffer2[offs] = dirtybuffer2[offs + 16] = 0;
	
				sx = offs / 32;
				sy = offs % 32;
				flipx = c1942_backgroundram.read(offs + 16) & 0x20;
				flipy = c1942_backgroundram.read(offs + 16) & 0x40;
				if (flipscreen != 0)
				{
					sx = 31 - sx;
					sy = 15 - sy;
					flipx = NOT(flipx);
					flipy = NOT(flipy);
				}
	
				drawgfx(tmpbitmap2,Machine.gfx[1],
						c1942_backgroundram.read(offs) + 2*(c1942_backgroundram.read(offs + 16) & 0x80),
						(c1942_backgroundram.read(offs + 16) & 0x1f) + 32 * c1942_palette_bank.read(),
						flipx,flipy,
						16 * sx,16 * sy,
						null,TRANSPARENCY_NONE,0);
			}
		}
	
	
		/* copy the background graphics */
		{
			int scroll;
	
	
			scroll = -(c1942_scroll.read(0) + 256 * c1942_scroll.read(1));
			if (flipscreen != 0) scroll = 256-scroll;
	
			copyscrollbitmap(bitmap,tmpbitmap2,1,new int[] {scroll},0,null,Machine.drv.visible_area,TRANSPARENCY_NONE,0);
		}
	
	
		/* Draw the sprites. */
		for (offs = spriteram_size[0] - 4;offs >= 0;offs -= 4)
		{
			int i,code,col,sx,sy,dir;
	
	
			code = (spriteram.read(offs) & 0x7f) + 4*(spriteram.read(offs + 1) & 0x20)
					+ 2*(spriteram.read(offs) & 0x80);
			col = spriteram.read(offs + 1) & 0x0f;
			sx = spriteram.read(offs + 3) - 0x10 * (spriteram.read(offs + 1) & 0x10);
			sy = spriteram.read(offs + 2);
			dir = 1;
			if (flipscreen != 0)
			{
				sx = 240 - sx;
				sy = 240 - sy;
				dir = -1;
			}
	
			/* handle double / quadruple height (actually width because this is a rotated game) */
			i = (spriteram.read(offs + 1) & 0xc0) >> 6;
			if (i == 2) i = 3;
	
			do
			{
				drawgfx(bitmap,Machine.gfx[2],
						code + i,col,
						flipscreen,flipscreen,
						sx,sy + 16 * i * dir,
						Machine.drv.visible_area,TRANSPARENCY_PEN,15);
	
				i--;
			} while (i >= 0);
		}
	
	
		/* draw the frontmost playfield. They are characters, but draw them as sprites */
		for (offs = videoram_size[0] - 1;offs >= 0;offs--)
		{
			if (videoram.read(offs) != 0x30)	/* don't draw spaces */
			{
				int sx,sy;
	
	
				sx = offs % 32;
				sy = offs / 32;
				if (flipscreen != 0)
				{
					sx = 31 - sx;
					sy = 31 - sy;
				}
	
				drawgfx(bitmap,Machine.gfx[0],
						videoram.read(offs) + 2 * (colorram.read(offs) & 0x80),
						colorram.read(offs) & 0x3f,
						flipscreen,flipscreen,
						8*sx,8*sy,
						Machine.drv.visible_area,TRANSPARENCY_PEN,0);
			}
		}
	} };
}
